package com.sdhs.web.controller.contract;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sdhs.common.annotation.Log;
import com.sdhs.common.constant.CacheConstants;
import com.sdhs.common.core.controller.BaseController;
import com.sdhs.common.core.domain.AjaxResult;
import com.sdhs.common.core.domain.entity.SysDept;
import com.sdhs.common.core.page.TableDataInfo;
import com.sdhs.common.enums.BusinessType;
import com.sdhs.common.utils.AESUtils;
import com.sdhs.common.utils.SecurityUtils;
import com.sdhs.common.utils.poi.ExcelUtil;
import com.sdhs.system.domain.GcContract;
import com.sdhs.system.domain.GcData;
import com.sdhs.system.service.IGcContractService;
import com.sdhs.system.service.ISysConfigService;
import com.sdhs.system.service.ISysDeptService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 合同主表Controller
 *整体实现逻辑是，通过ASE解密法务推送过来的数据，判断新增修改和删除，
 * @author add
 * @date 2025-04-04
 */
@RestController
@RequestMapping("/system/contract")
@Log4j2
public class GcContractController extends BaseController {
    @Autowired
    private IGcContractService gcContractService;

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private ISysConfigService configService;

    private static final String AES_KEY = "1234567890123456"; // 16字节密钥

    /**
     * 查询合同主表列表
     */
    @PreAuthorize("@ss.hasPermi('system:contract:list')")
    @GetMapping("/list")
    public TableDataInfo list(GcContract gcContract) {

        if(!SecurityUtils.isAdmin(SecurityUtils.getUserId())){
            SysDept sysDept = sysDeptService.selectCompanytByUserId(SecurityUtils.getDeptId());
            gcContract.setDeptId(sysDept.getDeptId());
            String ancestors = sysDept.getAncestors();
            // 将新的 deptId 添加到 ancestors 字符串中
            if (ancestors == null || ancestors.isEmpty()) {
                ancestors = String.valueOf(sysDept.getDeptId());
            } else {
                ancestors = ancestors + "," + sysDept.getDeptId();
            }
            gcContract.setAncestors(ancestors);

            Map<String, String> configMap = configService.selectConfigLikeKeyPrefix(CacheConstants.CONTRACT_CONFIG_KEY);
            if(configMap.containsKey(CacheConstants.CONTRACT_CONFIG_KEY + sysDept.getDeptId())){
                sysDept = sysDeptService.selectDeptById(configMap.get(CacheConstants.CONTRACT_CONFIG_KEY + sysDept.getDeptId()));
                gcContract.setDeptId(sysDept.getDeptId());
                gcContract.setAncestors(null);
            }
        }

        startPage();
        List<GcContract> list = gcContractService.selectGcContractList(gcContract);
        return getDataTable(list);
    }

    /**
     * 导出合同主表列表
     */
    @PreAuthorize("@ss.hasPermi('system:contract:export')")
    @Log(title = "合同主表", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, GcContract gcContract) {
        List<GcContract> list = gcContractService.selectGcContractList(gcContract);
        ExcelUtil<GcContract> util = new ExcelUtil<GcContract>(GcContract.class);
        util.exportExcel(response, list, "合同主表数据");
    }

    /**
     * 获取合同主表详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:contract:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(gcContractService.selectGcContractById(id));
    }


    @PostMapping("/addService")
    @ResponseBody
    public AjaxResult addService(HttpServletRequest req) {
        // 1. 获取并解密请求体
        String requestBody = getRequestBody(req);
        logger.info("请求数据: {}", req);

        try {
            String decryptedData = AESUtils.decrypt(requestBody);
            logger.debug("解密后数据: {}", decryptedData);

            // 2. 使用 Jackson 解析 JSON 字符串为 List<GcContract>
            ObjectMapper objectMapper = new ObjectMapper();
            List<GcContract> contracts = objectMapper.readValue(
                    decryptedData,
                    new TypeReference<List<GcContract>>() {}
            );

            logger.info("解析到 {} 条合同数据", contracts.size());
            // 3. 处理合同数据
            List<Object> failedItems = processContracts(contracts);
            if (!failedItems.isEmpty()) {
                logger.warn("处理完成，有 {} 条失败记录", failedItems.size());
            } else {
                logger.info("所有合同处理成功");
            }

            // 4. 返回处理结果
            return buildResponse(failedItems);

        } catch (Exception e) {
            e.printStackTrace();
            return new AjaxResult(500, "数据处理异常", null);
        }
    }

    /**
     * 处理合同列表并返回失败项
     */
    private List<Object> processContracts(List<GcContract> contracts) {
        List<Object> failedItems = new ArrayList<>();

        for (GcContract contract : contracts) {  // 改用增强for循环
            try {
                processSingleContract(contract, failedItems);
            } catch (Exception e) {
                e.printStackTrace();
                addFailedItem(failedItems, contract);
            }
        }

        return failedItems;
    }

    /**
     * 处理单个合同
     */
    private void processSingleContract(GcContract contract, List<Object> failedItems) {
        GcContract existingContract = gcContractService.selectGcContractByContractId(contract.getId());
        logger.info("处理单个合同请求数据: {}", contract);
        if (existingContract == null) {
            insertNewContract(contract, failedItems);
        } else {
            updateExistingContract(contract, failedItems);
        }
    }

    /**
     * 新增合同
     */
    private void insertNewContract(GcContract contract, List<Object> failedItems) {
        contract.setContractId(contract.getId());
        contract.setId(null);  // 清空ID让数据库自增

        int result = gcContractService.insertGcContract(contract);
        logger.info("新增合同信息: {}" + contract);
        logger.info(" 新增合同返回结果: " + result);
        if (result < 0) {
            addFailedItem(failedItems, contract);
        }
    }

    /**
     * 更新合同
     */
    private void updateExistingContract(GcContract contract, List<Object> failedItems) {
        contract.setContractId(contract.getId());

        int result = gcContractService.updateGcContract(contract);
        logger.info("请求数据: {}", contract);
        logger.info(" 返回结果: " + result);
        if (result < 0) {
            addFailedItem(failedItems, contract);
        }
    }

    /**
     * 添加失败项到列表
     */
    private void addFailedItem(List<Object> failedItems, GcContract contract) {
        failedItems.add(contract.getContractId());
    }

    /**
     * 构建响应结果
     */
    private AjaxResult buildResponse(List<Object> failedItems) {
        logger.info("构建响应结果:{} " , failedItems);
        if (!failedItems.isEmpty()) {
            String joinedString = StringUtils.join(failedItems, ",");
            logger.info("失败数据:{} " , joinedString);
            return new AjaxResult(500, "部分操作失败", joinedString);
        }
        return new AjaxResult(200, "操作成功", null);
    }

    /**
     * 新增合同主表
     */
    @PostMapping("/add")
    @ResponseBody
    public static String add(@RequestBody List<GcContract> gcContracts) {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // 1. List转JSON字符串
            String jsonData = objectMapper.writeValueAsString(gcContracts);
            System.out.println("Original JSON Data: " + jsonData);

            // 2. AES加密（可选）
            String encryptedData = AESUtils.encrypt(jsonData);
            System.out.println("加密后的数据: " + encryptedData);

            return encryptedData; // 或直接返回 jsonData
        } catch (JsonProcessingException e) {
            System.err.println("JSON序列化失败: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("加密失败: " + e.getMessage());
        }
        return "这个是一个异常"; // 或抛出自定义异常
    }

    /**
     * 修改合同主表
     * 根据合同id修改
     */
    @PreAuthorize("@ss.hasPermi('system:contract:edit')")
    @Log(title = "合同主表", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody GcContract gcContract) {
        return toAjax(gcContractService.updateGcContract(gcContract));
    }

    /**
     * 删除合同主表
     */
    @PreAuthorize("@ss.hasPermi('system:contract:remove')")
    @Log(title = "合同主表", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(gcContractService.deleteGcContractByIds(ids));
    }


    /*获取请求体*/
    public static String getRequestBody(HttpServletRequest request) {
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();
        String str = "";
        try {
            br = request.getReader();
            while ((str = br.readLine()) != null) {
                sb.append(str);
            }
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
            if (br != null) {
                try {
                    br.close();
                } catch (IOException eo) {
                    eo.printStackTrace();
                }
            }
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
}
